// --- 1. 类扩展 (extends) 与 super ---

// 定义一个基础的电视类
class Television {
  int _contrast = 50; // 添加一个私有字段用于 contrast 示例

  // 电视的基本开机流程
  void turnOn() {
    print("--- Television 开机流程 ---");
    _illuminateDisplay();
    _activateIrSensor();
    print("--------------------------");
  }

  // 私有辅助方法（用 print 模拟）
  void _illuminateDisplay() {
    print("📺 显示屏亮起...");
  }

  void _activateIrSensor() {
    print("📡 红外传感器已激活...");
  }

  // contrast 的 getter 和 setter
  int get contrast => _contrast;

  set contrast(int value) {
    print("Television 设置 contrast (int): $value");
    // 这里可以添加一些验证逻辑，比如范围检查
    if (value >= 0 && value <= 100) {
      _contrast = value;
    } else {
      print("警告：contrast 值 $value 超出范围 (0-100)");
    }
  }

  // 其他电视可能有的方法...
  void changeChannel(int channel) {
    print("切换到频道 $channel");
  }
}

// 定义一个智能电视类，继承自 Television
class SmartTelevision extends Television {
  // 重写父类的 turnOn 方法
  @override
  void turnOn() {
    print("--- SmartTelevision 开机流程 ---");
    // 调用父类的 turnOn 方法来执行基础流程
    super.turnOn();

    // 添加智能电视特有的开机步骤
    _bootNetworkInterface();
    _initializeMemory();
    _upgradeApps();
    print("-----------------------------");
  }

  // 智能电视特有的私有辅助方法（用 print 模拟）
  void _bootNetworkInterface() {
    print("🌐 网络接口启动...");
  }

  void _initializeMemory() {
    print("💾 内存初始化...");
  }

  void _upgradeApps() {
    print("📲 应用检查与升级...");
  }

  // --- 2. 成员覆盖 (@override) ---

  // 使用 @override 注解来明确表示我们正在覆盖父类的成员
  // 这里覆盖了 contrast 的 setter
  // 注意：参数类型从 int 变为了 num (int 的父类)，这是允许的 (类型放宽)
  @override
  set contrast(num value) {
    print("SmartTelevision 设置 contrast (num): $value");
    // 可以有不同的实现逻辑，或者调用父类实现
    // super.contrast = value.toInt(); // 如果想调用父类实现并转换类型

    // 这里我们用 SmartTV 自己的逻辑，允许小数但存储时取整
    int intValue = value.round(); // 四舍五入取整
    if (intValue >= 0 && intValue <= 100) {
      // 注意：这里访问的是继承自父类的私有字段 _contrast
      // Dart 中子类不能直接访问父类的私有成员。
      // 为了演示，我们假设 SmartTelevision 有自己的方式或通过 super 调用来设置
      // 更常见的做法是父类提供 protected (通过 _ 但在同一库中可访问) 或 public 方法
      // 这里为了简单，我们直接调用 super.contrast (假设父类setter能处理)
      super.contrast = intValue;
      print("SmartTV 将 contrast 设置为四舍五入后的值: $intValue");
    } else {
      print("警告 (SmartTV): contrast 值 $value (取整后 $intValue) 超出范围 (0-100)");
    }
  }

  // 智能电视特有的方法
  void browseInternet() {
    print("打开浏览器上网冲浪...🏄");
  }
}

// --- 3. noSuchMethod() ---

// 定义一个类，用于演示 noSuchMethod
class A {
  // 除非你覆盖 noSuchMethod，否则使用不存在的成员会导致 NoSuchMethodError。
  @override
  void noSuchMethod(Invocation invocation) {
    // invocation 对象包含了尝试调用的信息
    String memberName = invocation.memberName.toString();
    // Symbol('someMethod') -> "someMethod"
    memberName = memberName.substring(8, memberName.length - 2);

    print('捕获到错误！你想调用一个不存在的成员: $memberName');
    if (invocation.isMethod) {
      print('它是一个方法调用。');
      print('参数是: ${invocation.positionalArguments}');
    } else if (invocation.isGetter) {
      print('它是一个 getter 调用。');
    } else if (invocation.isSetter) {
      print('它是一个 setter 调用。');
      print('尝试设置的值是: ${invocation.positionalArguments.first}');
    }
  }
}

// --- Main Function ---
void main() {
  print('--- 演示类扩展 (extends) 与 super ---');
  var mySmartTV = SmartTelevision();
  mySmartTV.turnOn(); // 调用 SmartTelevision 的 turnOn，它内部会调用 super.turnOn()
  mySmartTV.changeChannel(5); // 调用继承自 Television 的方法
  mySmartTV.browseInternet(); // 调用 SmartTelevision 特有的方法
  print('');

  print('--- 演示成员覆盖 (@override) ---');
  print('初始 contrast: ${mySmartTV.contrast}');
  mySmartTV.contrast = 75; // 调用 SmartTelevision 的 setter (传入 int)
  print('设置 contrast = 75 后: ${mySmartTV.contrast}');
  mySmartTV.contrast =
      88.8; // 调用 SmartTelevision 的 setter (传入 double, 因为参数是 num)
  print('设置 contrast = 88.8 后: ${mySmartTV.contrast}'); // 会被四舍五入为 89
  mySmartTV.contrast = 120; // 尝试设置无效值
  print('尝试设置 contrast = 120 后: ${mySmartTV.contrast}'); // 值应保持不变
  print('');

  print('--- 演示 noSuchMethod() ---');
  var a = A();

  // 直接调用 a.nonExistentMethod() 会在编译时报错（除非 a 是 dynamic）
  // 为了触发 noSuchMethod，我们需要让编译器认为调用是合法的
  // 最常见的方式是使用 dynamic 类型

  // 将 a 视为 dynamic 类型
  dynamic dynamicA = a;

  print('尝试调用 dynamicA.nonExistentMethod(1, "hello")...');
  dynamicA.nonExistentMethod(1, "hello"); // 调用不存在的方法

  print('尝试访问 dynamicA.nonExistentGetter...');
  var _ = dynamicA.nonExistentGetter; // 访问不存在的 getter

  print('尝试设置 dynamicA.nonExistentSetter = true...');
  dynamicA.nonExistentSetter = true; // 调用不存在的 setter

  print('');
  print('--- 所有演示完成 ---');
}
